﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using AMStudio.DelegateDispather;
using AMStudio.Common;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace AMStudio.Common
{
    public class AWinFormModule : UserControl, IUserInterface
    {
        public object DataManager
        {
            get
            {
                return null;
            }
            set
            {
                ;
            }
        }

        protected IEventClient eventClient;
        public IEventClient EventClient
        {
            get
            {
                return eventClient;
            }
            set
            {
                eventClient = value;
            }
        }

        protected EventBroker eventBroker;
        public EventBroker EventBroker
        {
            get { return eventBroker; }
            set { eventBroker = value; }
        }

        protected AWinFormShell shell;
        public AWinFormShell Shell
        {
            get { return shell; }
            set { shell = value; }
        }

        private Hashtable RelatedDBTagCollection = new Hashtable();
        private Hashtable RelatedDBTagGroupCollection = new Hashtable();
        private System.Collections.Specialized.StringCollection subscribedEvents = new System.Collections.Specialized.StringCollection();

        private string desName = "MANAGER";
        private ContextMenuStrip menuControlTag;
        private System.ComponentModel.IContainer components;
        private ToolStripMenuItem MenuItemViewTag;
        private ToolStripMenuItem MenuItemEditTag;
        private ToolStripMenuItem viewLanguageToolStripMenuItem;
        private ToolStripMenuItem editLanguageToolStripMenuItem;
        private ThreadMessage threadMessage;
        private void InvokeIfNeeded(Action<object, object> whatToDo, object para1, object para2)
        {
            if (this.InvokeRequired)
                this.Invoke(whatToDo, para1, para2);
            else
                whatToDo(para1, para2);
        }
        private void OnValueChangedReceived(object sender, object e)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new ProcessingEventHandler(ValueChangedReceived), new object[] { sender, e });
                }
            }
            catch (Exception ex)
            {
                StationEventArgs content = (StationEventArgs)e;
                ExceptionManager ExManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();
                ExManager.HandleException(ex, "Policy");
                //Logging.WriteError(content.Command);
                //Logging.WriteException(ex);
            }
        }
        private void ValueChangedReceived(object sender, object content)
        {
            try
            {
                int n3 = Environment.TickCount;
                StationEventArgs e = (StationEventArgs)content;
                if (e.Command.IndexOf(this.UIName + "_ACTION") >= 0)
                {
                    Action<object> action = e.Value as Action<object>;
                    action(null);
                }

                else if (e.Command.IndexOf(this.UIName + "_GROUP_REFRESH") >= 0)
                {
                    StringValueList<UserInterfaceItem> items = e.Value as StringValueList<UserInterfaceItem>;
                    foreach (UserInterfaceItem item in items)
                    {
                        UIDB_RfreshTag(item);
                    }
                }
                else if (e.Command.IndexOf(this.UIName + "_SINGLE_REFRESH") >= 0)
                {
                    UserInterfaceItem item = e.Value as UserInterfaceItem;
                    UIDB_RfreshTag(item);
                }

                int n1 = Environment.TickCount - n3;
                this.BackGroud_EventHandler(sender, e);
                n3 = Environment.TickCount - n3;
            }
            catch (Exception ex)
            {
                //Logging.WriteException(ex);
                ExceptionManager ExManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();
                ExManager.HandleException(ex, "Policy");
            }
        }

        
        public string UIName = string.Empty;
        protected bool initialized = false;
        protected virtual void Initialize()
        {
            InitializeComponent();
            RuntimeDB.UITagCollection.Add(this.UIName, RelatedDBTagCollection);
            RuntimeDB.UITagGroupCollection.Add(this.UIName, RelatedDBTagGroupCollection);
            UIDB_InitializeControl(this);

            StringValueList<UserInterfaceItem> refreshItem = UserInterfaceDB.GetRefreshItemsForUI(this.UIName);
            for (int i = 0; i < refreshItem.Count; i++)
            {
                if (refreshItem[i].RelatedControl == null)
                {
                    UserInterfaceDB.DeleteItem(refreshItem[i]);
                }
            }

            //StringValueList<LanguageItem> refreshLangItem = LanguageDB.GetRefreshItemsForUI(this.UIName);

            //for (int i = 0; i < refreshLangItem.Count; i++)
            //{
            //    if (refreshLangItem[i].RelatedControl == null)
            //    {
            //        LanguageDB.DeleteItem(refreshLangItem[i]);
            //    }
            //}

            Language_InitializeControl(this);
        }
        public virtual bool ActivateUI()
        {
            if (!this.initialized)
            {
                this.Initialize();
                this.initialized = true;
            }
            SendMessage("ACTIVATE_UI", this.UIName);
            return true;
            //EventBroker.RegisterPublisher("ACTIVE_UI", this, "MODULE_EVENT");
        }
        protected virtual void BackGroud_EventHandler(object sender, StationEventArgs e)
        {
        }


        protected void SendMessage(string command, object data)
        {
            //currentCommand = command;
            //threadMessage = new ThreadMessage(desName, sourceName, command, data);
            threadMessage = new ThreadMessage(desName, UIName, command, data);
            QuenueManager.SendQueue(threadMessage);
        }
        protected void AddDBTagHandler(string relatedDBTags, System.Action<object, object> UIHandler)
        {
            Action<object, object> backgroundUIHandler = (p1, p2) =>
            {
                this.InvokeIfNeeded(UIHandler, p1, p2);
            };
            RelatedDBTagCollection.Add(relatedDBTags, backgroundUIHandler);
        }
        protected void AddDBTagGroupHandler(string relatedDBGroup, System.Action<object, object> UIHandler)
        {
            Action<object, object> backgroundUIHandler = (p1, p2) =>
            {
                this.InvokeIfNeeded(UIHandler, p1, p2);
            };
            RelatedDBTagGroupCollection.Add(relatedDBGroup, backgroundUIHandler);
        }
        protected void SubscribeEvent(string eventName)
        {
            subscribedEvents.Add(eventName);
            eventClient.SubscribeEvent(eventName, OnValueChangedReceived);
        }
        protected void UnSubscribeEvent(string eventName)
        {
            eventClient.UnSubscribeEvent(eventName, OnValueChangedReceived);
            subscribedEvents.Remove(eventName);
        }
        protected void ExcuteInBackGroud(Action<object> action)
        {
            SendMessage(this.UIName + "_ACTION" + Guid.NewGuid().ToString(), action);
        }
        protected void ShowException(Exception ex)
        {
            string message = (ex.Source + "\r\n" + ex.Message + "\r\n");
            Exception inner = ex.InnerException;
            while (inner != null)
            {
                message += (inner.Source + "\r\n" + inner.Message + "\r\n");
                inner = inner.InnerException;
            }
            DialogResult dlgRes = System.Windows.Forms.MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }


        protected override void Dispose(bool disposing)
        {
            foreach (string s in subscribedEvents)
            {
                eventClient.UnSubscribeEvent(s, OnValueChangedReceived);
            }
            subscribedEvents.Clear();
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.menuControlTag = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.MenuItemViewTag = new System.Windows.Forms.ToolStripMenuItem();
            this.MenuItemEditTag = new System.Windows.Forms.ToolStripMenuItem();
            this.viewLanguageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.editLanguageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.menuControlTag.SuspendLayout();
            this.SuspendLayout();
            // 
            // menuControlTag
            // 
            this.menuControlTag.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.MenuItemViewTag,
            this.MenuItemEditTag,
            this.viewLanguageToolStripMenuItem,
            this.editLanguageToolStripMenuItem});
            this.menuControlTag.Name = "menuControlTag";
            this.menuControlTag.Size = new System.Drawing.Size(165, 114);
            // 
            // MenuItemViewTag
            // 
            this.MenuItemViewTag.Name = "MenuItemViewTag";
            this.MenuItemViewTag.Size = new System.Drawing.Size(164, 22);
            this.MenuItemViewTag.Text = "&View Tag";
            this.MenuItemViewTag.Click += new System.EventHandler(this.MenuItemViewTag_Click);
            // 
            // MenuItemEditTag
            // 
            this.MenuItemEditTag.Name = "MenuItemEditTag";
            this.MenuItemEditTag.Size = new System.Drawing.Size(164, 22);
            this.MenuItemEditTag.Text = "&Edit Tag";
            this.MenuItemEditTag.Click += new System.EventHandler(this.MenuItemEditTag_Click);
            // 
            // viewLanguageToolStripMenuItem
            // 
            this.viewLanguageToolStripMenuItem.Name = "viewLanguageToolStripMenuItem";
            this.viewLanguageToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
            this.viewLanguageToolStripMenuItem.Text = "View &Language";
            this.viewLanguageToolStripMenuItem.Click += new System.EventHandler(this.viewLanguageToolStripMenuItem_Click);
            // 
            // editLanguageToolStripMenuItem
            // 
            this.editLanguageToolStripMenuItem.Name = "editLanguageToolStripMenuItem";
            this.editLanguageToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
            this.editLanguageToolStripMenuItem.Text = "Edit L&anguage";
            this.editLanguageToolStripMenuItem.Click += new System.EventHandler(this.editLanguageToolStripMenuItem_Click);
            // 
            // AWinFormModule
            // 
            this.Name = "AWinFormModule";
            this.menuControlTag.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        private void MenuItemViewTag_Click(object sender, EventArgs e)
        {
            string tagName = this.UIName + "." + this.menuControlTag.SourceControl.Name;
            UserInterfaceItem tagItem = UserInterfaceDB.UIDBTags[tagName] as UserInterfaceItem;
            UserInterfaceTagForm form;
            if (tagItem == null)
            {
                tagItem = new UserInterfaceItem();
                tagItem.UIName = this.UIName;
                tagItem.ControlName = this.menuControlTag.SourceControl.Name;
                form = new UserInterfaceTagForm(tagItem, false, true);
            }
            else
            {
                form = new UserInterfaceTagForm(tagItem, false, false);
            }
            if (form.ShowDialog() == DialogResult.OK)
            {

            }
        }
        private void MenuItemEditTag_Click(object sender, EventArgs e)
        {
            string tagName = this.UIName + "." + this.menuControlTag.SourceControl.Name;
            UserInterfaceItem tagItem = UserInterfaceDB.UIDBTags[tagName] as UserInterfaceItem;
            UserInterfaceTagForm form;
            if (tagItem == null)
            {
                tagItem = new UserInterfaceItem();
                tagItem.UIName = this.UIName;
                tagItem.ControlName = this.menuControlTag.SourceControl.Name;
                form = new UserInterfaceTagForm(tagItem, true, true);
                //form.Location = this.menuControlTag.SourceControl.Location;
            }
            else
            {
                form = new UserInterfaceTagForm(tagItem, true, false);
            }
            DialogResult ret = form.ShowDialog();
            if (ret == DialogResult.OK)
            {
                tagItem.RelatedControl = this.menuControlTag.SourceControl;
                UserInterfaceDB.SaveItemChange(this.UIName, this.menuControlTag.SourceControl.Name, tagItem);
                UIDB_ConnectTagAction(tagItem);
                this.ActivateUI();                  
            }
            else if (ret == DialogResult.Ignore)
            {
                UserInterfaceDB.SaveItemChange(this.UIName, this.menuControlTag.SourceControl.Name, null);
            }
        }

        protected void UIDB_InitializeControl(Control UIControl)
        {
            if (UIControl.Controls == null)
                return;
            foreach (Control c in UIControl.Controls)
            {
                if (c is AWinFormModule)
                    continue;
             
                if (UserDB.CurrentLoginUser.AuthorizationSet == 0)
                {
                    c.ContextMenuStrip = this.menuControlTag;
                }
                else
                {
                    c.ContextMenuStrip = null;
                }
               
                UserInterfaceItem item = UserInterfaceDB.UIDBTags[this.UIName + "." + c.Name] as UserInterfaceItem;
                if (item != null)
                {
                    item.RelatedControl = c;
                    //string displayTag = item.DisplayTag.Trim();
                    //string displayRefreshGroup = item.DisplayRefreshGroup;
                    if (!string.IsNullOrEmpty(item.Action))
                    {
                        this.UIDB_ConnectTagAction(item);
                    }
                }
                if (c.Controls != null)
                {
                    UIDB_InitializeControl(c);
                }
            }
        }
        protected virtual void UIDB_RfreshTag(UserInterfaceItem item)
        {

        }
        protected virtual void UIDB_ConnectTagAction(UserInterfaceItem item)
        {
            //this.Click += (sender, e) =>
            //{
            //    SendMessage("UIITEM_ACTION", item);
            //};
        }


        //public string LanguageString = "en_US";
        public static string LanguageString = "中文";
        private void viewLanguageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tagName = this.UIName + "." + this.menuControlTag.SourceControl.Name;
            LanguageItem tagItem = LanguageDB.UIDBTags[tagName] as LanguageItem;
            LanguageTagForm form;
            if (tagItem == null)
            {
                tagItem = new LanguageItem();
                tagItem.UIName = this.UIName;
                tagItem.ControlName = this.menuControlTag.SourceControl.Name;
                form = new LanguageTagForm(tagItem, false, true,LanguageString);
            }
            else
            {
                form = new LanguageTagForm(tagItem, false, false, LanguageString);
            }
            if (form.ShowDialog() == DialogResult.OK)
            {

            }
        }
        private void editLanguageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tagName = this.UIName + "." + this.menuControlTag.SourceControl.Name;
            LanguageItem tagItem = LanguageDB.UIDBTags[tagName] as LanguageItem;
            LanguageTagForm form;
            if (tagItem == null)
            {
                tagItem = new LanguageItem();
                tagItem.UIName = this.UIName;
                tagItem.ControlName = this.menuControlTag.SourceControl.Name;
                form = new LanguageTagForm(tagItem, true, true, LanguageString);
            }
            else
            {
                form = new LanguageTagForm(tagItem, true, false, LanguageString);
            }
            DialogResult ret = form.ShowDialog();
            if (ret == DialogResult.OK)
            {
                tagItem.RelatedControl = this.menuControlTag.SourceControl;
                LanguageDB.SaveItemChange(this.UIName, this.menuControlTag.SourceControl.Name, tagItem);
                Language_RfreshTag(tagItem);
            }
            else if (ret == DialogResult.Ignore)
            {
                LanguageDB.SaveItemChange(this.UIName, this.menuControlTag.SourceControl.Name, null);
            }
        }
        protected virtual void Language_InitializeControl(Control UIControl)
        {
            if (UIControl.Controls == null)
                return;
            foreach (Control c in UIControl.Controls)
            {
                if (c is AWinFormModule)
                    continue;
                
                if (UserDB.CurrentLoginUser.AuthorizationSet == 0)
                {
                    c.ContextMenuStrip = this.menuControlTag;
                }
                else
                {
                    c.ContextMenuStrip = null;
                }
                
                LanguageItem item = LanguageDB.UIDBTags[this.UIName + "." + c.Name] as LanguageItem;
                if (item != null)
                {
                    item.RelatedControl = c;
                    if (item.Language.ContainsKey(LanguageString))
                    {
                        this.Language_RfreshTag(item);
                    }
                }
                if (c.Controls != null)
                {
                    Language_InitializeControl(c);
                }
            }
        }
        protected virtual void Language_RfreshTag(LanguageItem item)
        {
            item.RelatedControl.Text = item.Language[LanguageString].ToString();
        }
    }
}
